/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package CiaAerea;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.text.*;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;

/**
 *
 * @author Thomas
 */
public class CiaAerea implements Serializable{

    private Hashtable<String, Cliente> cliente = new Hashtable<String, Cliente>();
    private Hashtable<Integer, Voo> voo = new Hashtable<Integer, Voo>();
    private Hashtable<Integer, Destino> destino = new Hashtable<Integer, Destino>();
    private Hashtable<String, Aeronave> aeronave = new Hashtable<String, Aeronave>();
    private Hashtable<Integer, Reserva> reserva = new Hashtable<Integer, Reserva>();
    private static int qtdeDestino = 0;
    private static int qtdeAeronaves = 0;

    public Endereco cadastrarEndereco(Endereco dest) throws Exception {

        Endereco novoEndereco = new Endereco();
        //Receber do usuario
        novoEndereco.setRua(dest.getRua());

        //Receber do usuario
        novoEndereco.setBairro(dest.getBairro());

        //Receber do usuario
        novoEndereco.setComplemento(dest.getComplemento());

        //Receber do usuario
        novoEndereco.setNumero(dest.getNumero());

        //Receber do usuario
        novoEndereco.setCEP(dest.getCEP());

        //Receber do usuario
        novoEndereco.setCidade(dest.getCidade());

        //Receber do usuario
        novoEndereco.setEstado(dest.getEstado());

        //Receber do usuario
        novoEndereco.setPais(dest.getPais());

        return novoEndereco;
    }

    public void cadastrarDestino(int cod, String Cidade, String Aeroporto, int Fuso, double Distancia, Endereco EndDest) throws Exception {

        Destino dest = new Destino(cod, Cidade, Aeroporto, Fuso, Distancia, EndDest);

        try {
            if (destino.isEmpty()) {
                destino.put(cod, dest);
                System.out.println("Destino cadastrado com sucesso!");
                qtdeDestino++;
            } else if (destino.get(cod) != null) {
                System.out.println("Destino já existente!");
            } else {
                destino.put(cod, dest);
                System.out.println("Destino cadastrada com sucesso!");
                qtdeDestino++;
            }
        } catch (Exception err) {
            JOptionPane.showMessageDialog(null, err.getMessage());
        }
    }

    public void removerDestino(int codDestino) throws Exception {
        Voo auxVoo;


        //Pega o Voo associado a esse destino
        auxVoo = destino.get((codDestino)).getVooDestino();

        //Se houver um voo associado a esse destino
        if (auxVoo != null) {
            //Remover esse voo
            removerVoo(auxVoo.getCodigoIdentificador());
        }

        //Remover o Destino
        if (destino.get(codDestino) != null) {
            destino.remove((codDestino));
        }

    }

    public void alterarDestino(int codDestino, String Cidade, String Aeroporto, int Fuso, double Distancia, Endereco dest) throws Exception {

        try {
            destino.get((codDestino)).setNomeCidade(Cidade);
            destino.get((codDestino)).setNomeAeroporto(Aeroporto);
            destino.get((codDestino)).setFusoHorario(Fuso);
            destino.get((codDestino)).setDistanciaBase(Distancia);
            destino.get((codDestino)).setEnderecoAeroporto(dest);
        } catch (Exception err) {
            JOptionPane.showMessageDialog(null, err.getMessage());
        }


    }

    public void cadastrarAeronave(String prefixoIdentificador, String modelo, int autonomia,
            int numTotalFileiras, int numAssentosPorFileira, int numFileirasExecutiva, int numFileirasEconomica) throws Exception {

        Aeronave dados = new Aeronave(prefixoIdentificador, modelo, autonomia, numTotalFileiras, numAssentosPorFileira, numFileirasExecutiva, numFileirasEconomica);

        try {

            if (aeronave.isEmpty()) {
                aeronave.put(prefixoIdentificador, dados);
                System.out.println("Aeronave cadastrada com sucesso!");

            } else if (aeronave.get(prefixoIdentificador) != null) {
                System.out.println("Aeronave já existente!");
            } else {
                aeronave.put(prefixoIdentificador, dados);
                System.out.println("Aeronave cadastrada com sucesso!");
            }
        } catch (Exception er) {
            JOptionPane.showMessageDialog(null, er.getMessage());
        }


    }

    public void removerAeronave(String prefixoIdentificador) throws Exception {
        ArrayList<Voo> vooAeronave;
        int codVoo;

        vooAeronave = aeronave.get(prefixoIdentificador).getAllVoo();

        //Se houver voo associados a essa aeronave
        if (vooAeronave != null) {
            for (int i = 0; i < vooAeronave.size(); i++) {
                codVoo = vooAeronave.get(i).getCodigoIdentificador();

                removerVoo(codVoo);
            }
        }

        aeronave.remove(prefixoIdentificador);


    }

    public void alterarAeronave(String prefixoIdentificador, String modelo, int autonomia,
            int numTotalFileiras, int numAssentosPorFileira, int numFileirasExecutiva, int numFileirasEconomica) throws Exception {


        aeronave.get(prefixoIdentificador).setModelo(modelo);
        aeronave.get(prefixoIdentificador).setAutonomia(autonomia);
        aeronave.get(prefixoIdentificador).setNumTotalFileiras(numTotalFileiras);
        aeronave.get(prefixoIdentificador).setNumAssentosPorFileira(numAssentosPorFileira);
        aeronave.get(prefixoIdentificador).setNumFileirasExecutiva(numFileirasExecutiva);
        aeronave.get(prefixoIdentificador).setNumFileirasEconomica(numFileirasEconomica);


    }

    public Aeronave buscaAeronaveDisponivel(Voo viagem) throws Exception {
        boolean encontrou = false;
        String chave = new String();
        
        ArrayList<Aeronave> aeronave;
        Aeronave dados = new Aeronave();
        
       final File folderNave = new File("Aeronave/");

       aeronave = dados.listaAeronaves(folderNave);

       int qtdeNaves = aeronave.size();
       Aeronave naveEscolhida = new Aeronave();
       
       for(int i=0; i<qtdeNaves && encontrou==false;i++)
       {
          chave = aeronave.get(i).getPrefixoIdentificador();
          
          encontrou = verificaDisponibilidade(viagem.getDestinoVoo(),viagem,aeronave.get(i));
       
//          Se encontou a nave, então associá-la ao Voo
            if (encontrou) {
                // System.out.println("Cod nave: " +naveEscolhida.getPrefixoIdentificador());
                naveEscolhida = aeronave.get(i);
                viagem.setAeronaveVoo(naveEscolhida);
            }
       
       }
        
        
//        Enumeration<String> chavesReserva = aeronave.keys();
//        Aeronave naveEscolhida = new Aeronave();
//
//        //Percorre a lista de aeronaves até o final da lista ou encontrar uma disponivel
//        while (chavesReserva.hasMoreElements() && encontrou == false) {
//            chave = chavesReserva.nextElement();
//
//
//            encontrou = verificaDisponibilidade(destino.get(viagem.getDestinoVoo().getcodigoIdentificador()), viagem, aeronave.get(chave));
//
//            //Se encontou a nave, então associá-la ao Voo
//            if (encontrou) {
//                // System.out.println("Cod nave: " +naveEscolhida.getPrefixoIdentificador());
//                naveEscolhida = aeronave.get(chave);
//                viagem.setAeronaveVoo(naveEscolhida);
//            }
//
//        }

        return naveEscolhida;

    }

    public void setAeronaveDisponivel(boolean encontrou, Voo viagem, String chave) throws Exception {
        Double novaHora = 0.0;
        StringBuilder novaData = new StringBuilder();
        int troca;
        String aux;
        String auxFinalDecimo;


        //Se encontrou uma aeronave disponivel
        if (encontrou) {
            //Nova hora e igual a DistanciaBase * 2 + 2 acrescentada a hora de voo
            novaHora = Double.parseDouble(viagem.getHora()) + (destino.get(viagem.getDestinoVoo().getcodigoIdentificador()).getDistanciaBase() * 2) + 2;

            novaData = new StringBuilder(viagem.getData());

            //Enquanto novaHora for maior ou igual 24, some dias a novaData
            while (novaHora >= 24) {
                //Troca recebe o valor do dia + 1
                troca = Character.getNumericValue(novaData.charAt(1)) + 1;

                //Necessario para utilizar o charSetAt da StringBuilder
                aux = "" + troca;

                //Acrescenta o numero da troca ao dia da novaData
                //novaData.setCharAt(1, aux.charAt(0));


                //Se o dia for maior que 09, muda a casa decimal
                if (troca > 9) {

                    troca = Character.getNumericValue(novaData.charAt(0)) + 1;
                    auxFinalDecimo = "" + troca;
                    novaData.setCharAt(0, auxFinalDecimo.charAt(0));
                    novaData.setCharAt(1, '0');
                } //Se nao for, acrescenta um dia normalmente
                else {
                    novaData.setCharAt(1, aux.charAt(0));
                }

                //Considera-se que todos os meses tem 30 dias
                //Se o dia for igual a 31, muda o mes
                if (novaData.charAt(0) == '3' && novaData.charAt(1) == '1') {
                    //Se for Setembro
                    if (novaData.charAt(4) == '9') {
                        novaData.setCharAt(3, '1');
                        novaData.setCharAt(4, '0');
                        novaData.setCharAt(0, '0');
                        novaData.setCharAt(1, '1');

                    } //Se for Outubro
                    else if (novaData.charAt(4) == '0') {

                        novaData.setCharAt(4, '1');
                        novaData.setCharAt(0, '0');
                        novaData.setCharAt(1, '1');

                    } //Se for Novembro
                    else if (novaData.charAt(3) == '1' && novaData.charAt(4) == '1') {
                        novaData.setCharAt(4, '2');
                        novaData.setCharAt(0, '0');
                        novaData.setCharAt(1, '1');
                    } //Se for entre Janeiro e Agosto
                    else {
                        troca = Character.getNumericValue(novaData.charAt(4)) + 1;
                        auxFinalDecimo = "" + troca;

                        novaData.setCharAt(4, auxFinalDecimo.charAt(0));

                        novaData.setCharAt(0, '0');
                        novaData.setCharAt(1, '1');
                    }
                }

                //Decresce 24 horas da novaHora ja que um dia foi acrescentado
                novaHora -= 24;

            }


            //System.out.println("Nova Data: " +novaData);
            //System.out.println("Nova Hora: " +novaHora);    
            aeronave.get(chave).setDataDisponivel(novaData.toString());
            aeronave.get(chave).setHoraDisponivel(novaHora.toString());

        }
    }

    public void cadastrarVoo(int Vcod, String Vdata, String Vhora, double VPEc, double VPEx, int codigoIdentificador)
            throws Exception {


        Aeronave naveEscolhida;
        String chave = new String();
        try {
            Voo viagem = new Voo(Vcod, Vdata, Vhora, VPEc, VPEx, destino.get(codigoIdentificador));

            naveEscolhida = buscaAeronaveDisponivel(viagem);


            if (naveEscolhida.getPrefixoIdentificador() != null) {
                chave = naveEscolhida.getPrefixoIdentificador();
                setAeronaveDisponivel(true, viagem, chave);


                //Se o Hashtable estiver vazio
                if (voo.isEmpty()) {
                    //Adicinando Voo ao Hashtable
                    voo.put(Vcod, viagem);

                    //Adicionando vínculos do Voo para destino e aeronave
                    destino.get(codigoIdentificador).setVooDestino(viagem);
                    naveEscolhida.setvooAeronave(viagem);

                    System.out.println("Voo cadastrado com sucesso!");

                } else if (voo.get(Vcod) != null) //Caso essa posição já tenha alguém
                {
                    System.out.println("Voo já existente!");
                } else //Cadastrar o Voo
                {
                    voo.put(Vcod, viagem);
                    destino.get(codigoIdentificador).setVooDestino(viagem);
                    naveEscolhida.setvooAeronave(viagem);
                    System.out.println("Voo cadastrado com sucesso!");
                }
            } else {
                System.out.println("Nenhuma aeronave disponivel! Voo nao cadastrado.");
            }
        } catch (Exception err) {
            JOptionPane.showMessageDialog(null, err.getMessage());
            System.out.println("Entrei Voo CiaAerea");
        }

    }

    public void removerVoo(int codigoVoo) throws Exception {
        int codReserva, codDestino;
        String cpfCliente, codAeronave;

        //Pegando todos os reservas daquele Voo
        Enumeration<Integer> reservaVoo = voo.get(codigoVoo).getAllReservaVoo();

        Integer chave;
        //Se houver reservas associados a esse voo
        if (reservaVoo != null) {

            //Enquanto houverem chaves de reservas
            while (reservaVoo.hasMoreElements()) {
                //Pegue a chave se possuir elemento
                chave = reservaVoo.nextElement();

                //Se existir a reserva
                if (reserva.get(chave) != null) {
                    //Pegar o código da reserva
                    codReserva = reserva.get(chave).getCodReserva();

                    //Pegar o cpf do cliente dessa reserva
                    cpfCliente = reserva.get(chave).getClienteReserva().getCpf();

                    //Se existir esse cliente 
                    if (cliente.get(cpfCliente) != null) {
                        //Removendo o vínculo da reserva removida com o cliente que a comprou
                        cliente.get(cpfCliente).removeReservaCliente(codigoVoo);
                    }

                    //Remove a reserva
                    if (reserva.get(codReserva) != null) {
                        reserva.remove(codReserva);
                    }
                }
            }

        }

        //Remover o vínculo do voo com a Aeronave. Aeronave ->Cod(Voo->Aeronave->Pref) -> Remove
        if (voo.get(codigoVoo).getAeronaveVoo() != null) {
            codAeronave = voo.get(codigoVoo).getAeronaveVoo().getPrefixoIdentificador();
            aeronave.get(codAeronave).removeVoo(codigoVoo);
            //Voltando a sua disponibilidade para default
            aeronave.get(codAeronave).setDataDisponivel("00/00");
            aeronave.get(codAeronave).setHoraDisponivel("0");
        }


        //Remover o vínculo do voo com a Aeronave. Destino ->Cod(Voo->Destino->Cod) -> Remove
        if (voo.get(codigoVoo).getDestinoVoo() != null) {
            codDestino = voo.get(codigoVoo).getDestinoVoo().getcodigoIdentificador();
            destino.get(codDestino).setVooDestino(null);
        }


        //Remoção do Voo
        if (voo.get(codigoVoo) != null) {
            voo.remove(codigoVoo);
        }
    }

    public void alterarVoo(int codigoVoo, String data, String hora, double VPEc, double VPEx, Destino dest)
            throws Exception {

        if (voo.get(codigoVoo) == null) {
            System.out.println("Campo nave vazio");
        } else {
            voo.get(codigoVoo).setData(data);
            voo.get(codigoVoo).setHora(hora);
            voo.get(codigoVoo).setValorPassagemEconomica(VPEc);
            voo.get(codigoVoo).setValorPassagemExecutiva(VPEx);
            voo.get(codigoVoo).setDestinoVoo(dest);

        }
    }

    public void cadastrarCliente(String nome, String cpf, String eMail,
            String telefone, String celular, boolean isClienteFidelidade, String numeroFidelidade, Endereco end) throws Exception {

        Cliente novoCliente = new Cliente(nome, cpf, eMail, telefone, celular, isClienteFidelidade, numeroFidelidade, end);
        try {
            //Se o Hashtable estiver vazio
            if (cliente.isEmpty()) {
                cliente.put(cpf, novoCliente);
                System.out.println("Cliente cadastrado com sucesso!");

            } else if (cliente.get(cpf) != null) //Caso essa posição já tenha alguém
            {
                System.out.println("Cliente já existente!");
            } else //Cadastrar o cliente
            {
                cliente.put(cpf, novoCliente);
                System.out.println("Cliente cadastrado com sucesso!");
            }
        } catch (Exception er) {
            JOptionPane.showMessageDialog(null, er.getMessage());
        }




    }

    public void removerCliente(String cpfCliente) throws Exception {
        int numeroAssento, codReserva, codVoo;
        char fileiraAssento;


        //Pegar todas as reservas efetuadas por esse cliente
        Enumeration<Integer> auxReserva = cliente.get(cpfCliente).getallReservaCliente();
        Integer chave;

        //Se houver reservas associadas a esse cliente
        if (auxReserva != null) {

            //Enquanto houverem chaves de reservas
            while (auxReserva.hasMoreElements()) {
                //Pegue a chave se possuir elemento
                chave = auxReserva.nextElement();

                //Pegando o código da Reserva
                codReserva = reserva.get(chave).getCodReserva();

                //Pegando a posição da fileira e assento
                fileiraAssento = reserva.get(codReserva).getFileiraAssento();
                numeroAssento = reserva.get(codReserva).getNumeroAssento();

                //Pegando o código do voo
                codVoo = reserva.get(chave).getVooReserva().getCodigoIdentificador();

                //Alterando o mapa de assento para vago
                voo.get(codVoo).setDesocupacao(fileiraAssento, numeroAssento);

                //Removendo o vínculo da reserva ao Voo
                if (voo.get(codVoo).getReservaVoo(codReserva) != null) {
                    voo.get(codVoo).removeReserva(codReserva);
                }

                //Removendo a reserva do ArrayList
                if (reserva.get(codReserva) != null) {
                    reserva.remove(codReserva);
                }
            }
        }

        //Removendo o cliente do ArrayList
        if (cliente.get(cpfCliente) != null) {
            cliente.remove(cpfCliente);
        }

    }

    public void alterarCliente(String nome, String cpf, String eMail,
            String telefone, String celular, boolean isClienteFidelidade, String numeroFidelidade, Endereco end) throws Exception {

        cliente.get(cpf).setNome(nome);
        cliente.get(cpf).seteMail(eMail);
        cliente.get(cpf).setTelefone(telefone);
        cliente.get(cpf).setCelular(celular);
        cliente.get(cpf).setIsClienteFidelidade(isClienteFidelidade);
        cliente.get(cpf).setNumeroFidelidade(numeroFidelidade);
        cliente.get(cpf).setEndereco(end);
        /*cliente.get(cpf).getEndereco().setBairro(end.getBairro());
         cliente.get(cpf).getEndereco().setRua(end.getRua());
         cliente.get(cpf).getEndereco().setCEP(end.getCEP());
         cliente.get(cpf).getEndereco().setCidade(end.getCidade());
         cliente.get(cpf).getEndereco().setEstado(end.getEstado());
         cliente.get(cpf).getEndereco().setNumero(end.getNumero());
         cliente.get(cpf).getEndereco().setComplemento(end.getComplemento());
         cliente.get(cpf).getEndereco().setPais(end.getPais());*/


    }

    public boolean efetuarReserva(int codReserva, int codigoVoo, char fileira, int assento, boolean executivo, String cpfCliente)
            throws Exception {
        boolean efetuou = false;

        if (!voo.get(codigoVoo).AssentoOcupado(fileira, assento)) {
            if (voo.get(codigoVoo) == null || cliente.get(cpfCliente) == null) {
                throw new Exception("Voo ou Cliente Inexistente!");
            } else {
                efetuou = true;
                //Criando o objeto reserva
                Reserva novaReserva = new Reserva(codReserva, fileira, assento, executivo, voo.get(codigoVoo), cliente.get(cpfCliente));

                //Alterando no mapa de assento a posição para ocupado
                voo.get(codigoVoo).setOcupacao(fileira, assento);

                //Relacionando Reserva ao voo
                voo.get(codigoVoo).setReservaVoo(novaReserva);

                //Relacionando Reserva ao cliente 
                cliente.get(cpfCliente).setReservaCliente(novaReserva);

                //Guardando a reserva no Hash
                reserva.put(codReserva, novaReserva);

                System.out.println("Reserva efetuada com sucesso!");
            }

        } else {
            throw new Exception("Esse assento está ocupado!");
        }

        return efetuou;

    }

    //Interessante ter o código da reserva, numero e fileira inconsistente
    public boolean cancelarReserva(int codigoReserva)
            throws Exception {
        boolean efetuou = false;
        int codigoVoo;
        String cpfCliente;


        //Pegando os códigos do cliente e voo, respectivamente
        cpfCliente = reserva.get(codigoReserva).getClienteReserva().getCpf();
        codigoVoo = reserva.get(codigoReserva).getVooReserva().getCodigoIdentificador();

        //Verifica se há uma reserva com esse cliente nesse Voo
        if (reserva.get(codigoReserva) != null) {
            //Pegando o número do assento e sua fileira
            char fileiraAssento = reserva.get(codigoReserva).getFileiraAssento();
            int numeroAssento = reserva.get(codigoReserva).getNumeroAssento();

            //Alterando o mapa de assento para vago
            voo.get(codigoVoo).setDesocupacao(fileiraAssento, numeroAssento);

            //Removendo o vínculo da reserva ao Voo
            voo.get(codigoVoo).removeReserva(codigoReserva);

            //Removendo o vínculoda reserva ao Cliente
            cliente.get(cpfCliente).removeReservaCliente(codigoReserva);

            reserva.remove(codigoReserva);

            efetuou = true;
        } else {
            //Não foi possível efetuar o cancelamento. Ou o Cliente ou o Voo, não possui essa reserva
            efetuou = false;
            throw new Exception("Nao foi possivel efetuar o cancelamento da reserva");
        }


        return efetuou;
    }

    public double estimarFaturamentoOtimista() {
        double valor = 0;
        int codReserva;     
        
        FaturamentoSerialize dados = new FaturamentoSerialize();
        ArrayList<Voo> voo;
        ArrayList<ReservaSerialize> reserva;
        
//        final File folderVoo = new File("Voos/");
//        final File folderReserva = new File("Reservas/");
//        voo = dados.listaVoos(folderVoo);
//        reserva = dados.listaReservas(folderReserva);
//        
//        //Pegando todas as chaves da hashtable reserva e guardando na estrutura enumeration
//        Enumeration<Integer> chavesReserva = reserva.keys();
//
//        //Irá guardar a posição dessa chave
//        Integer chave;
//
//        //Enquanto houverem chaves de reservas
//        while (chavesReserva.hasMoreElements()) {
//            //Pegue a chave se possuir elemento
//            chave = chavesReserva.nextElement();
//
//            //Através da posição da chave, pegar o código dessa reserva
//            codReserva = reserva.get(chave).getVooReserva().getCodigoIdentificador();
//
//            //Então calcule o valor do voo, verificando se é executiva ou não
//            if (reserva.get(chave).isIsExecutiva()) {
//                valor += voo.get(codReserva).getValorPassagemExecutiva();
//            } else {
//                valor += voo.get(codReserva).getValorPassagemEconomica();
//            }
//        }

        return valor;

    }

    public double estimarFaturamentoPessimista() {
        double valor = 0;

        //Estimando 10% do valor, através do faturamento otimista
        valor = estimarFaturamentoOtimista() * 0.1;

        return valor;

    }

    public boolean verificaDisponibilidade(Destino destino, Voo voo, Aeronave nave) {
        boolean encontrou = false;
         
      

        try {

            //Declara e inicializa os objetos do tipo Data  
            SimpleDateFormat format = new SimpleDateFormat("dd/MM");
            Date dataVoo = format.parse(voo.getData());
            Date dataDisponivel = format.parse(nave.getDataDisponivel());

            //Se a autonomia da aeronave for menor que a distancia base
            //O processo nao e continuada
            if (nave.getAutonomia() < destino.getDistanciaBase()) {
                System.out.println("Aeronave nao possui autonomia suficiente!");
            } //Se a autonomia da aeronave for suficiente,verifica se a data disponivel da aeronave
            //e maior que a data de voo, se sim, com certeza a aeronave esta disponivel
            else if (dataVoo.compareTo(dataDisponivel) > 0) {
                encontrou = true;
            } //Se a data do voo for a mesma da data disponivel da aeronave, verifica
            //a hora de disponibilidade e a hora do voo
            else if (dataVoo.compareTo(dataDisponivel) == 0) {

                if (Double.parseDouble(voo.getHora()) >= Double.parseDouble(nave.getHoraDisponivel())) {

                    encontrou = true;
                }
            } //Se nenhum dos criterios foi atingido, essa aeronave nao esta disponivel
            else {
                System.out.println("Aeronave indisponivel!");
            }


        } catch (ParseException | NumberFormatException e) {
            System.out.println(e);
        }

      return encontrou;  

    }

    public Destino getDestino(int id) {
        return destino.get(id);
    }

    public Voo getVoo(int cod) {
        return voo.get(cod);
    }

    public Aeronave getAeronave(String prefId) {

        return aeronave.get(prefId);
    }

    public Cliente getCliente(String cpfCliente) {

        return cliente.get(cpfCliente);
    }

    public Reserva getReserva(int codigoVoo) {

        return reserva.get(codigoVoo);

    }
    
    public void serializarCliente() throws IOException{
        
        FileOutputStream fileOut = new FileOutputStream("Cliente.ser");
        ObjectOutputStream out = new ObjectOutputStream(fileOut);
        
        out.writeObject(cliente);
        out.close();
        
    }

    public void unserializeCliente() throws IOException, ClassNotFoundException{
        
        FileInputStream fileIn = new FileInputStream("Cliente.ser");
        ObjectInputStream in = new ObjectInputStream(fileIn);
        
        cliente = (Hashtable)in.readObject();
    }
    
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws Exception {
        // TODO code application logic here
        CiaAerea sistema = new CiaAerea();

        //Cadastrando Endereco para cliente - String rua, String bairro, String complemento, String numero, String CEP, String cidade, String estado, String pais
        Endereco enderecoCliente = new Endereco("Pedro Alvares", "Jd Vila", "Nao tem", "414", "07055051", "Guarulhos", "Sao Paulo", "Brasil");
        //Cadastrando Cliente - String nome, String cpf, String eMail, String telefone, String celular, boolean isClienteFidelidade, String numeroFidelidade, Endereco end     
        sistema.cadastrarCliente("Guimarães", "39918191805", "email", "1234", "8765", false, "666", enderecoCliente);
        sistema.cadastrarCliente("Rosa", "41061855805", "email", "1234", "8765", false, "555", enderecoCliente);
        //Alterando Cliente


        //Cadastrando Endereco para destino
        //Endereco enderecoDestino = new Endereco("Aeroporto de Cumbica", "Centro", "Nao tem", "101", "07055051", "Guarulhos", "Sao Paulo", "Brasil");
        //Cadastrando Destino - int cod,String Cidade, String Aeroporto,int Fuso, double Distancia, Endereco end
        //sistema.cadastrarDestino(1, "Guarulhos", "Aeroporto Internacional", 3, 24, enderecoDestino);
        //sistema.cadastrarDestino(2, "Campinas", "Viracopos", 3, 24, enderecoDestino);
        //sistema.cadastrarDestino(1, "Guarulhos", "Aeroporto Internacional", 3, 24, enderecoDestino);


        //Cadastrando Aeronave - String prefixoIdentificador, String modelo, int autonomia,int numTotalFileiras, int numAssentosPorFileira, int numFileirasExecutiva, int numFileirasEconomica        
        //.cadastrarAeronave("A108", "Boing", 600, 500, 10, 50, 150);
        //sistema.cadastrarAeronave("A109", "Boing II", 600, 500, 10, 50, 150);
        //Alterando Aeronave

        //Cadastrando Voo - int Vcod, String Vdata, String Vhora, double VPEc, double VPEx, Destino destino
        //sistema.cadastrarVoo(309, "07/02", "23", 300.00, 500.00, 1);
        //sistema.cadastrarVoo(378, "01/03", "23", 300.00, 500.00, 1);
        //sistema.cadastrarVoo(379, "01/03", "23", 300.00, 500.00, 1);
        //Alterando Voo - Precisa de mais cadastros
        //sistema.alterarVoo(sistema.getAeronave("A108"), 309, 3, sistema.getDestino(1));

        //Efetuando reserva - int codReserva, int codigoVoo, int fileira, char assento, boolean executivo, String cpfCliente
        //sistema.efetuarReserva(980, 309, 'A', 1, false, "41061855805");
        //sistema.efetuarReserva(1000, 379, 'A', 2, true, "41061855805");
        //sistema.efetuarReserva(990, 309, 'A', 1, true, "41061855805");



        System.out.println("O faturamento otimista e de: " + sistema.estimarFaturamentoOtimista());
        System.out.println("O faturamento pessimista e de: " + sistema.estimarFaturamentoPessimista());

        Interface i = new Interface(sistema);


//        //As remoções funcionam individualmente
//        sistema.cancelarReserva(980);
//        sistema.removerCliente("123");
//        sistema.removerVoo(309);
//        sistema.removerAeronave("A108");
//        sistema.removerDestino(1);



    }
}
